package com.youmu.shop.order.service.impl;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.shop.weixin.util.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;

import com.exception.BizException;
import com.exception.ParamException;
import com.youmu.shop.admin.dao.AdminDao;
import com.youmu.shop.biz.bean.DispatchingParam;
import com.youmu.shop.biz.bean.LatLng;
import com.youmu.shop.biz.bean.LatLngBean;
import com.youmu.shop.cart.dao.CartDao;
import com.youmu.shop.cart.domain.Cart;
import com.youmu.shop.common.utils.ConfigUtil;
import com.youmu.shop.common.utils.DateUtil;
import com.youmu.shop.common.utils.GeoUtil;
import com.youmu.shop.common.utils.JsonUtil;
import com.youmu.shop.common.utils.OrderUtil;
import com.youmu.shop.common.utils.WeixinToolUtil;
import com.youmu.shop.common.utils.WeixinUtil;
import com.youmu.shop.constants.CouponStatusConst;
import com.youmu.shop.constants.OrderStatusConst;
import com.youmu.shop.context.utils.SessionContext;
import com.youmu.shop.context.utils.UserContext;
import com.youmu.shop.coupon.bean.CouponCodeBean;
import com.youmu.shop.coupon.dao.CouponDao;
import com.youmu.shop.http.utils.HttpUtil;
import com.youmu.shop.integral.bean.IntegralLog;
import com.youmu.shop.integral.dao.IntegralDao;
import com.youmu.shop.json.utils.JacksonUtil;
import com.youmu.shop.order.bean.OrderBean;
import com.youmu.shop.order.bean.OrderItemBean;
import com.youmu.shop.order.dao.OrderDao;
import com.youmu.shop.order.service.OrderService;
import com.youmu.shop.order.vo.DispatchingOrder;
import com.youmu.shop.order.vo.OrderDetailVo;
import com.youmu.shop.order.vo.OrderVo;
import com.youmu.shop.order.vo.ShippingMethodVo;
import com.youmu.shop.param.CalculateFreightParam;
import com.youmu.shop.product.dao.ProductDao;
import com.youmu.shop.receiver.dao.ReceiverDao;
import com.youmu.shop.receiver.vo.ReceiverVO;
import com.youmu.shop.response.BaiduMapResponse;
import com.youmu.shop.response.FreightResponse;
import com.youmu.shop.role.dao.RoleDao;
import com.youmu.shop.shop.dao.ShopDao;
import com.youmu.shop.system.bean.Admin;
import com.youmu.shop.system.bean.MemberRank;
import com.youmu.shop.system.bean.Role;
import com.youmu.shop.system.bean.Shop;
import com.youmu.shop.system.bean.User;
import com.youmu.shop.user.dao.UserDao;

import net.sf.json.JSONObject;

@Service
public class OrderServiceImpl implements OrderService{

	@Autowired
    private OrderDao orderDao;
	
	@Autowired
    private UserDao userDao;
	
	@Autowired
    private IntegralDao integralDao;
	
	@Autowired
    private CouponDao couponDao;
	
	@Autowired
    private ProductDao productDao;
	
	@Autowired
    private CartDao cartDao;
	
	@Autowired
	private RoleDao roleDao;
	
	@Autowired
	private ShopDao shopDao;
	
	@Autowired
	private AdminDao adminDao;
	
	ExecutorService notifyPool = Executors.newCachedThreadPool();
	
	@Resource
	private ReceiverDao receiverDao;

    private Logger logger = LoggerFactory.getLogger(getClass());

	
	@Override
	public List<OrderVo> findOrderByStatus(Integer orderStatus,Long userId) {
		return orderDao.findOrderByStatus(orderStatus,null, null, userId);
	}

	@Override
	public OrderDetailVo findOrderDetail(Long orderId) {
		return orderDao.findOrderDetail(orderId);
	}

	@Override
	public long createOrder(OrderBean orderBean) {
	    
	    if(orderBean.getTotalAmount()==OrderStatusConst.ZERO){
            throw new BizException("未选择商品！");
        }
	    
		String createOrderNumber = OrderUtil.createOrderNumber(orderBean.getMember());
		orderBean.setSn(createOrderNumber);
		orderBean.setOrderStatus(OrderStatusConst.ZERO);
		orderBean.setCreateDate(new Date());
		orderBean.setFee(new BigDecimal(orderBean.getToolPrice()));
		if(orderBean.getShopingPoint() == null) {
		    orderBean.setShopingPoint(0);
		}
//        //判断若有抵扣积分，则扣除相应的积分，若无，则不对用户进行任何处理
//        if(orderBean.getShopingPoint()!=null&&orderBean.getShopingPoint()!=0){
//        	User user = (User) userDao.getById(orderBean.getMember());
//        	if(user==null){
//        		throw new BizException("未找到用户");
//        	}
//        	//订单抵扣的积分
//        	int shoppingPoint = orderBean.getShopingPoint();
//        	//重新计算用户积分
//        	int userPoint = user.getPoint() - shoppingPoint;
//        	if(userPoint<0){
//            	throw new BizException("积分不足,抵扣失败");
//            }else{
//            	user.setPoint(userPoint);
//            	//扣除积分后更新
//            	userDao.update(user);
//            }
//        }
		
		//1、保存订单主表
		List<OrderItemBean> orderItemBeans = orderBean.getOrderItemBeans();
		if(orderItemBeans.isEmpty()){
			throw new BizException("未选择商品项");
		}
		List<ReceiverVO>  receiverVOs = receiverDao.findReceiver(UserContext.getUserInfo().getId(), null, orderBean.getReceiveId());
		ReceiverVO vo = receiverVOs.get(0);
        orderBean.setReceiverPhone(vo.getPhone());
		orderBean.setReceiverName(vo.getConsignee());
		orderDao.save(orderBean);
		
		//2、保存订单明细
		if(orderItemBeans.size()>0 && orderItemBeans != null){
			orderDao.batchSaveOrderItemDetail(orderItemBeans,orderBean.getId());
		}
		
//		//3、更新优惠劵状态
//        if(orderBean.getCouponCode()!=null){
//            CouponCodeBean couponCodeBean = (CouponCodeBean) couponDao.getById(orderBean.getCouponCode());
//            couponCodeBean.setIsUsed(CouponStatusConst.ALREADY_USED);
//            couponDao.update(couponCodeBean);
//        }
		
		//4、判断清除购物车中的部分商品
		for (OrderItemBean orderItemBean : orderItemBeans) {
			//若是从购物车来的商品
			if(orderItemBean.getCartId()!=null){
				//则根据购物车id清除该用户的购物车项
				cartDao.update(new Cart(orderItemBean.getCartId(),true));
			}
		}
		
		return orderBean.getId();
	}

	@Override
	public Map<String, Object> payWeixin(Long orderId, Double amount, String ip) {
		OrderBean order = orderDao.getById(orderId);
		if(order == null){
			throw new ParamException("订单不能为空");
		}
		//判断订单状态是否为待支付
		if (order.getOrderStatus() != OrderStatusConst.ZERO) {
			throw new BizException("不是待支付，不能付款");
		}
		//判断订单是否超时(30分钟为超时时间)
//		if(order.getCreateDate()==null){
//			throw new ParamException("没有下单时间");
//		}
//		if(DateUtil.getDateBeforeHalfHour(order.getCreateDate())>30){
//			throw new ParamException("订单支付超时");
//		}
		//判断支付金额是否等于订单实付款金额
//		if (!amount.equals(order.getAmountPaid())) {
//			throw new BizException("订单金额与实际支付金额不符");
//		}
		
		//设置外部订单号
		String outSn = UUID.randomUUID().toString().replaceAll("-","");
        order.setOutSn(outSn);
		orderDao.update(order);
		
		//调用支付接口，返回支付info 
		Map<String, Object> weinxinMap = new HashMap<>();
		if(amount > 0) {
    		String prepayid = WeixinUtil.payUnifiedorder(UserContext.getUserInfo().getUsername(), "微信支付订单", order.getOutSn(), amount, ip);
            weinxinMap.put("appId", ConfigUtil.getWeixinAppId());
            weinxinMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            weinxinMap.put("nonceStr", UUID.randomUUID().toString().replaceAll("-",""));
            weinxinMap.put("package", "prepay_id="+prepayid);
            weinxinMap.put("signType", "MD5");
            String paySign = WeixinToolUtil.getSign(weinxinMap);
            weinxinMap.put("paySign", paySign);
		} else {
		    notifySuccess(outSn);
		}
        return weinxinMap;
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public String notifyWeixin(String body) {
		Map<String,Object> result = new HashMap();
		Map params = WeixinToolUtil.getMapByXml(body);
        if(params == null){
            result.put("return_code", "false");
            result.put("return_msg", "参数错误");
            return WeixinToolUtil.getXml(result);
        }
        
        String sign =WeixinToolUtil.getSign(params);
        String paramSign = (String) params.get("sign");
        if(paramSign == null ||!paramSign.equals(sign)){
            result.put("return_code", "false");
            result.put("return_msg", "签名错误");
            return WeixinToolUtil.getXml(result);
        }
        String outOrderNumber = (String) params.get("out_trade_no");
        if(!this.notifySuccess(outOrderNumber)){
            result.put("return_code", "false");
            return WeixinToolUtil.getXml(result);
        }
        result.put("return_code", "success");
        return WeixinToolUtil.getXml(result);
	}
	
	/**
	 * 微信回调成功
	 * @param outSn
	 * @return
	 */
	private boolean notifySuccess(String outSn){
        final OrderBean order = orderDao.getByOutSn(outSn);
        if(order == null){
            return false;
        }
        // 判断订单是否处理完成 
        if(order.getOrderStatus() >= OrderStatusConst.ONE) {
            return true;
        }
        //更改订单状态
        Long method = order.getShippingMethod();
        if(method.intValue() == 4) {
            order.setOrderStatus(OrderStatusConst.ONE);
        } else {
            order.setOrderStatus(OrderStatusConst.THREE);
        }
        
        //更新用户消费总积分
        final User user = (User) userDao.getById(order.getMember());
        int point = user.getPoint();
        int totalPoint = user.getTotalPoint();
        logger .info("******order sucess, user point handle******");
        logger.info("user old point {}, user old total point {}.", point, totalPoint);
        
        // 商品的积分加
        int addPonit = (int) order.getTotalAmount();
        // 用户抵扣商品的积分 1 - 0.01
        int negPoint = order.getShopingPoint() == null ? 0 : order.getShopingPoint(); 
        logger.info("user point used {}, user buy product create point {}.", negPoint, addPonit);
        
        point = (int) Math.max(0, point + addPonit - negPoint);
        totalPoint = totalPoint + addPonit;
        logger.info("user new point {}, user new total point {}.", point, totalPoint);
        user.setPoint(point);
        user.setTotalPoint(totalPoint);
        logger .info("------order sucess, user point handle----");
        
        // 修改用户的等级 根据当前积分
        MemberRank rank =  userDao.selectMemberRankByPoint(totalPoint);
        if(!rank.getId().equals(user.getMemberRankId())) {
            // 升级用户
            user.setMemberRankId(rank.getId());
        }else {
            // 不升级
            user.setMemberRankId(null);
        }
        userDao.update(user);
        
        
        //生成积分消费记录
        if(negPoint > 0) {
            integralDao.savelog(new IntegralLog(1, order.getShopingPoint(), order.getMember(), order.getId()));
        }
        
        /*
         * 消耗优惠劵
         */
        if(order.getCouponCode()!=null){
        	CouponCodeBean couponCodeBean = (CouponCodeBean) couponDao.getById(order.getCouponCode());
        	couponCodeBean.setUsedDate(new Date());
        	couponCodeBean.setIsUsed(CouponStatusConst.ALREADY_USED);
        	couponDao.update(couponCodeBean);
        }
        
        //更新订单
        orderDao.update(order);
        notifyOrderPaySucess(order, user);
        return true;
    }

    /**
     * 
     * @param order
     * @param user
     */
    private void notifyOrderPaySucess(final OrderBean order, final User user) {
        // -------- 提示 ---- 
        notifyPool.execute(new Runnable() {
            
            @Override
            public void run() {
                try {
                    // 提示已经支付
                    String accessToken = UserContext.getAccessToken();
                    if(StringUtils.hasText(accessToken)) {
                        WeixinToolUtil.connectWeiXinInterface(user.getUserName(), accessToken,
                            MessageFormat.format("您的订单{0}已经支付成功，我们会尽快为您安排配送。", order.getSn()));
                    }
                    
                    // 配送消息推送
                    // 查询所有的配送员
                    List<Long> roles = Arrays.asList(7L, 10L, 11L);
                    Long method = order.getShippingMethod();
                    switch(method.intValue()) {
                        // 自营
                        case 4:
                            roles = Arrays.asList(7L);
                            break;
                        // 闪送
                        case 6:
                            roles = Arrays.asList(10L);
                            break;
                        // 快递
                        default:
                            roles = Arrays.asList(11L);
                            break;
                            
                    }
                    List<Admin> admins = adminDao.selectAdminInRoles(roles);
                    for (Admin a : admins) {
                        String sendTime = order.getSendTime();
                        if(StringUtils.hasText(sendTime)) {
                            WeixinToolUtil.connectWeiXinInterface(a.getUsername(), accessToken,
                            MessageFormat.format("您有新的订单了，订单号（{0}）请于{1}之前送达，非常感谢！", order.getSn(), sendTime));
                        } else {
                            WeixinToolUtil.connectWeiXinInterface(a.getUsername(), accessToken,
                                MessageFormat.format("您有新的订单了，订单号（{0}）请尽快送达，非常感谢！", order.getSn()));
                        }
                    }
                } catch (Exception e) {
                    logger.error("支付成功通知失败", e);
                }
            }
        });
    }

	@Override
	@Transactional
	public void cancelOrder(Long id) {
		OrderBean orderBean = orderDao.getById(id);
		if(orderBean==null){
			throw new ParamException("未查询到该订单");
		}
		if(orderBean.getOrderStatus()!=OrderStatusConst.ZERO){
			throw new ParamException("不是待支付订单，不能取消");
		}
		//更新该订单为已取消
		orderDao.cancelOrder(id);
		
		//若有优惠劵，则释放占用的优惠劵
		if(orderBean.getCouponCode()!=null){
			CouponCodeBean couponCodeBean = (CouponCodeBean)couponDao.getById(orderBean.getCouponCode());
			couponCodeBean.setIsUsed(CouponStatusConst.USABLE);
			couponDao.update(couponCodeBean);
		}
		
		//若有抵扣积分，则释放占用的积分
		Integer orderPoint = orderBean.getShopingPoint();
		if(orderPoint!=null&&orderPoint!=0){
			User user = (User) userDao.getById(orderBean.getMember());
			user.setPoint(user.getPoint()+orderPoint);
			userDao.update(user);
		}
	}

	@Override
	public List<OrderItemBean> getBuyAgain(Long orderId) {
		OrderBean orderBean = orderDao.findItemsByOrderId(orderId);
		if(orderBean.getOrderStatus()!=OrderStatusConst.SIX){
			throw new ParamException("该订单并未完成");
		}
		return orderBean.getOrderItemBeans();
		
	}

	@Override
	public double getShopingPointByUserId(Long userId) {
		//获取用户积分（1积分 == 1元）
		User user = (User) userDao.getById(userId);
		if(user == null){
			throw new ParamException("无该用户信息");
		}
		return user.getPoint();
	}

	@Override
	public String getShippingByOrderId(Long orderId) {
		return orderDao.getShippingByOrderId(orderId);
	}

	@Override
	public Double getPaidAmountByInfo(Long orderId, Long userId) {
		OrderBean orderBean = orderDao.getById(orderId);
		User user = (User) userDao.getById(userId);
		if(orderBean==null){
			throw new ParamException("无该订单信息");
		}
		if(user==null){
			throw new ParamException("无用户信息");
		}
		return orderDao.getPaidAmountByInfo(orderId,userId);
	}

    /** 
     * @see com.youmu.shop.order.service.OrderService#getShippingMethod(java.lang.Long)
     */
    @Override
    public List<ShippingMethodVo> getShippingMethod() {
        return orderDao.getShippingMethod();
    }

	@Override
	public List<DispatchingOrder> selectOrdersForDispatchingAdmin(Admin admin, Integer orderStatus, Integer currentPage) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<Role> roles = roleDao.selectRolesByAdminId(admin.getId());
		Integer orders = null;
		for (Role role : roles) {
			/**
			 * 自营
			 */
			if(role.getId() == 7L){
				orders = 1;
			}
			
			/**
			 * 闪送
			 */
			if(role.getId() == 10){
				orders = 2;
			}
			
			/**
             * 快递
             */
            if(role.getId() == 11){
                orders = 3;
            }
		}
		map.put("orders", orders);
		map.put("orderStatus", orderStatus);
		map.put("start", (currentPage - 1) * 2);
		List<DispatchingOrder> list = orderDao.selectOrdersForDispatchingAdmin(map);
		for (DispatchingOrder dispatchingOrder : list) {
			dispatchingOrder.setOrderItems(this.selectOrderItemsByOrder(dispatchingOrder.getOrderId()));
		}
		return list;
	}

	@Override
	public List<OrderItemBean> selectOrderItemsByOrder(Long orderId) {
		return orderDao.selectOrderItemsByOrder(orderId);
	}
//	 * 1、自营配送员
//     * 2、第三方闪送配送员
//     * 3、快递配送员
	@Override
	@Transactional
	public void orderTaking(ServletContext servletContext,DispatchingParam dispatchingParam,Admin admin) {
		Integer dispatchingType = dispatchingParam.getDispatchingType();
		Integer orderStatus = null;
		List<Long> orderList = dispatchingParam.getOrderList();
		for (Long orderId : orderList) {
			OrderBean orderBean = orderDao.selectByPrimaryKey(orderId);
			if(orderBean.getOrderStatus() == 2 || orderBean.getOrderStatus() >= 4) {
			    throw new BizException(MessageFormat.format("订单{0}已经接单，请重新选择！", orderBean.getSn()));
			}
			orderBean.setFlashMen(dispatchingParam.getFlashMen());
			orderBean.setFlashMenPhone(dispatchingParam.getFlashMenPhone());
			orderBean.setSnOut(dispatchingParam.getSnOut());
			orderBean.setPosterId(dispatchingParam.getPosterId());
			orderBean.setWorkerConfirmedTime(new Date());
			String content = null;
	        switch (dispatchingType) {
	       case 2:
	           content = MessageFormat.format("您的订单（{0}）正在配送途中，请您耐心等待准备签收。配送员：{1}电话：{2}。", orderBean.getSn(), orderBean.getFlashMen(), orderBean.getFlashMenPhone());
               orderStatus = 2;
	          break;
	        case 3:
	            content = MessageFormat.format("您的订单（{0}）已发货，承运公司:{1}。运单编号：{2}。", 
	                    orderBean.getSn(), orderBean.getShippingMethod() == 5 ? "圆通快递" : orderBean.getShippingMethod() == 7 ? "顺丰快递" : "其它快递",
	                        orderBean.getSnOut());
	            orderStatus = 4;
	            break;
	        default:
	            content = MessageFormat.format("您的订单（{0}）正在配送途中，请您耐心等待准备签收。配送员：{1}电话：{2}。", orderBean.getSn(), admin.getName(), admin.getPhone());
	            orderStatus = 2;
	            break;
	        }
	        orderBean.setOrderStatus(orderStatus);
	        orderDao.orderTaking(orderBean);
			this.sendWeiXinMessageForDispatching(orderBean.getSn(), admin, userDao.selectByUserId(orderBean.getMember()), servletContext, content);
		}
	}

	@Override
	public List<DispatchingOrder> selectDispatchingByAdmin(Admin admin, Integer orderStatus, Integer currentPage) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("posterId", admin.getId());
		map.put("orderStatus", orderStatus);
		map.put("dispatchingType", admin.getDispatchingType());
		map.put("start", (currentPage - 1) * 2);
		List<DispatchingOrder> list = orderDao.selectDispatchingByAdmin(map);
		for (DispatchingOrder dispatchingOrder : list) {
			dispatchingOrder.setOrderItems(this.selectOrderItemsByOrder(dispatchingOrder.getOrderId()));
		}
		return list;
	}
	
	/**
	 * 接单推送消息
	 * @param orderNo
	 * @param user
	 * @param servletContext
	 */
	private void sendWeiXinMessageForDispatching(String orderNo,Admin admin, User user, ServletContext servletContext, String context){
		if(context == null){
			return;
		}
		Object accessToken = servletContext.getAttribute(ConfigUtil.getWeiXinTokenKey());
		if(org.springframework.util.StringUtils.isEmpty(accessToken)){
			String url = ConfigUtil.getWeixinBasicGetAccessToken().replace("APPID", ConfigUtil.getWeixinAppId()).replace("APPSECRET", ConfigUtil.getWeixinAppSecre());
			JSONObject jsonObject = CommonUtil.httpsRequest(url, "GET", null);
			if(StringUtils.isEmpty(jsonObject.getString("access_token"))){
				throw new RuntimeException("请求执行token出错"+ jsonObject.getInt("errcode") + jsonObject.getString("errmsg"));
			}
			servletContext.setAttribute(ConfigUtil.getWeiXinTokenKey(),jsonObject.getString("access_token"));
		}
		WeixinToolUtil.connectWeiXinInterface(user.getUserName(), (String)servletContext.getAttribute(ConfigUtil.getWeiXinTokenKey()),  context);
	}

	@Override
	public void orderFinish(ServletContext servletContext, DispatchingParam dispatchingParam, Admin admin) {
		Integer orderStatus = 5;
		List<Long> orderList = dispatchingParam.getOrderList();
		for (Long orderId : orderList) {
			OrderBean orderBean = new OrderBean();
			orderBean.setId(orderId);
			orderBean.setOrderStatus(orderStatus);
			orderBean.setWorkerReceivedTime(new Date());
			orderDao.orderTaking(orderBean);
		}
	}

	@Override
	public Object calculateFreightByProductTypeAndReceiverAddress(CalculateFreightParam calculateFreightParam) throws Exception {
		FreightResponse freightResponse = new FreightResponse();
		String[] proeductArrs = calculateFreightParam.getProductIds().split(",");
		/**
		 * 是否含有新鲜商品标识，0未含有，1含有
		 */
		Integer hasFreshGood = 0;
		for (int i = 0; i < proeductArrs.length; i++) {
			Boolean isCake = productDao.getIsCakeById(Long.parseLong(proeductArrs[i]));
			if(isCake != null && isCake){
				hasFreshGood = 1;
				break;
			}
		}
		/**
		 * 先判断是否为成都地区
		 */
		if(this.isChengduForAddress(calculateFreightParam.getCityCode())){
			/**
			 * 获取经纬度对象
			 */
			String jsonStr = HttpUtil.sendGet(ConfigUtil.getBaiduMapAddressToLongitudeAndLatitude()
					.replace("Address", calculateFreightParam.getReceiverAddress()));
			BaiduMapResponse baiduMapResponse = JsonUtil.fromJson(jsonStr, BaiduMapResponse.class);
			/**
			 * 由价格低到高寻找适合的自营盘配送圈子
			 */
			LatLngBean latLngBean = baiduMapResponse.getResult();
			if(null == latLngBean.getLocation()){
				throw new RuntimeException("地址填写有误，请重新填写");
			}
			LatLng latLng = latLngBean.getLocation();
			List<Shop> selfSupportShops = this.selectSelfSupportShipping();
			for (Shop shop : selfSupportShops) {
				List<LatLng> latLngs = JacksonUtil.json2listT(shop.getPosition(), LatLng.class);
				if(GeoUtil.isPolygonContainsPoint(latLng, latLngs)){
					if(hasFreshGood.equals(1)){
						freightResponse.setSuppotType(1);
						freightResponse.setShippingMethod(4L);
						if(DateUtil.compareDateStrAndEquals(calculateFreightParam.getSendTime(), "20:00:00") &&
								DateUtil.compareDateStr("22:00:00", calculateFreightParam.getSendTime())){
							freightResponse.setShippingPrice(shop.getNigtPrice());
						}else{
							freightResponse.setShippingPrice(shop.getDayPrice());
						}
					}else{
						/**
						 *	非自营且没有新鲜的不支持闪送，
						 *	即为快递配送
						 */
						freightResponse.setSuppotType(3);
						/**
						 * 快递配送方式数据封装
						 */
						Map<String, Object> map = new HashMap<String, Object>();
						if(this.isSichuanForAddress(calculateFreightParam.getProvinceCode())){
							map.put("cityCode", calculateFreightParam.getCityCode());
						}else{
							map.put("provinceCode", calculateFreightParam.getProvinceCode());
						}
						List<Shop> list = this.selectExpressShippings(map);
						freightResponse.setExpressShippings(list);
					}
					break;
				}
			}
			/**
			 * 筛选完毕后配送价格为空表示不在自营圈子内
			 * 则为闪送或者快递
			 */
			if(StringUtils.isEmpty(freightResponse.getShippingPrice())){
				/**
				 * 闪送仅仅在有新鲜商品的时候支持闪送
				 */
				if(hasFreshGood.equals(1)){
					List<Shop> sendFlashShops = this.selectSendFlash();
					for (Shop shop : sendFlashShops) {
						List<LatLng> latLngs = JacksonUtil.json2listT(shop.getPosition(), LatLng.class);
						if(GeoUtil.isPolygonContainsPoint(latLng, latLngs)){
							freightResponse.setSuppotType(2);
							freightResponse.setShippingMethod(6L);
							if(DateUtil.compareDateStrAndEquals(calculateFreightParam.getSendTime(), "18:00:00") &&
									DateUtil.compareDateStr("20:00:00", calculateFreightParam.getSendTime())){
								freightResponse.setShippingPrice(shop.getNigtPrice());
							}else{
								freightResponse.setShippingPrice(shop.getDayPrice());
							}
							break;
						}
					}
					if(freightResponse.getShippingPrice() == null){
						throw new RuntimeException("新鲜商品超出配送范围，请变更收货地址");
					}
				}else{
					/**
					 *	非自营且没有新鲜的不支持闪送，
					 *	即为快递配送
					 */
					freightResponse.setSuppotType(3);
					/**
					 * 快递配送方式数据封装
					 */
					Map<String, Object> map = new HashMap<String, Object>();
					if(this.isSichuanForAddress(calculateFreightParam.getProvinceCode())){
						map.put("cityCode", calculateFreightParam.getCityCode());
					}else{
						map.put("provinceCode", calculateFreightParam.getProvinceCode());
					}
					List<Shop> list = this.selectExpressShippings(map);
					freightResponse.setExpressShippings(list);
				}
			}
			
		}else{
			freightResponse.setSuppotType(3);
			if(hasFreshGood.equals(1)){
				throw new RuntimeException("您所买的商品包含仅限成都地区配送，请重新选择配送地址");
			}
			/**
			 * 快递配送方式数据封装
			 */
			Map<String, Object> map = new HashMap<String, Object>();
			if(this.isSichuanForAddress(calculateFreightParam.getProvinceCode())){
				map.put("cityCode", calculateFreightParam.getCityCode());
			}else{
				map.put("provinceCode", calculateFreightParam.getProvinceCode());
			}
			List<Shop> list = this.selectExpressShippings(map);
			freightResponse.setExpressShippings(list);
		}
		return freightResponse;
	}
	
	/**
	 * 判断地址码是否为成都
	 * @param cityCode
	 * @return
	 */
	private Boolean isChengduForAddress(Integer cityCode){
		return cityCode.equals(5101);
	}
	
	/**
	 * 获得快递配送方式以及费用
	 * @param map
	 * @return
	 */
	private List<Shop> selectExpressShippings(Map<String, Object> map){
		return shopDao.selectExpressShippingsForProvinceCode(map);
	}
	
	/**
	 * 判断是否为四川境内
	 * @param provinceCode
	 * @return
	 */
	private Boolean isSichuanForAddress(Integer provinceCode){
		return provinceCode.equals(51);
	}

	@Override
	public List<Shop> selectSelfSupportShipping() {
		return shopDao.selectSelfSupportShipping();
	}

	@Override
	public List<Shop> selectSendFlash() {
		return shopDao.selectSendFlash();
	}

	@Override
	public Integer confirmReceipt(Long orderId) {
		return orderDao.confirmReceipt(orderId);
	}
}
